const select = document.getElementById('com-select')
let ports = undefined
select.addEventListener('click', async () => {
    const new_ports = await window.electronAPI.SerialPortList('com')
    // console.log(new_ports); // 打印串口列表
    if (JSON.stringify(ports) != JSON.stringify(new_ports)) {
        select.innerHTML = ''; // 清除所有子元素
        ports = new_ports;
        new_ports.forEach(item => {
            if (item.path) { // 确保 path 存在
                const option = document.createElement('option'); // 创建 <option> 元素
                option.value = item.path; // 设置 <option> 的 value 属性
                option.textContent = item.path; // 设置 <option> 的显示文本
                select.appendChild(option); // 将 <option> 添加到 <select> 中
            }
        })
    }
})

const link = document.getElementById('com-link')
const close = document.getElementById('com-close')
const connection_status = document.getElementById('connection-status')
let link_port = null
let link_state = false
link.addEventListener('click', async () => {
    if (link_state == false && ports != undefined) {
        link_state = true
        ports.forEach(async item => {
            if (select.value == item.path) {
                const message = await window.electronAPI.LinkSerialPort(item.path)
                // console.log(message)
                connection_status.textContent = "已链接"
                id_read_sp = await read_sp()
            }
        })
    }
})
close.addEventListener('click', async () => {
    if (link_state == true && ports != undefined) {
        const message = await window.electronAPI.CloseSerialPort(link_port)
        // console.log(message)
        link_state = false
        connection_status.textContent = "未链接"
        clearInterval(id_read_sp)
    }
})

let buffer = '';
let read = []
let id_read_sp = null
const view_side_data = document.getElementById('view-side-data')
const view_side_data_clear = document.getElementById('view-side-data-clear')

view_side_data_clear.addEventListener('click', async () => {
    view_side_data.innerHTML = '';
})
async function extractJson(buffer) {
  let balance = 0; // 括号平衡计数器
  let start = -1; // JSON 对象的起始位置
  let end = -1; // JSON 对象的结束位置

  for (let i = 0; i < buffer.length; i++) {
    const char = buffer[i];

    if (char === '{') {
      if (balance === 0) {
        start = i; // 记录 JSON 对象的起始位置
      }
      balance++; // 遇到 '{'，平衡计数器加 1
    } else if (char === '}') {
      balance--; // 遇到 '}'，平衡计数器减 1
      if (balance === 0) {
        end = i + 1; // 记录 JSON 对象的结束位置
        break; // 找到一个完整的 JSON 对象，退出循环
      }
    }
  }

  if (start !== -1 && end !== -1) {
    const jsonStr = buffer.substring(start, end)
    return {jsonStr, end}; // 返回完整的 JSON 字符串
  }

  return null; // 没有找到完整的 JSON 对象，返回 null
}
async function read_sp() {
    const decoder = new TextDecoder('utf-8');
    id_read_sp = setInterval(async () => {
        const message = await window.electronAPI.ReadSerialPort(link_port)
        if (message != null) {
            const utf8String = decoder.decode(message);
            buffer += utf8String;
            while (1) {
                const {jsonStr, end} = await extractJson(buffer)
                if (jsonStr) {
                    buffer = buffer.substring(end);

                    const json_string = JSON.parse(jsonStr)
                    //防止收到重复的值
                    if (JSON.stringify(json_string.current_position) !== 
                        JSON.stringify(read[read.length - 1])) {

                        await update_xyz(json_string)
                        
                        if (read.length > 15) {
                            // 如果长度超过 15，删除最早的 5 个值
                            read = read.slice(5);
                        }
                        read.push(json_string.current_position)
                        }
                } else {
                    break
                }
            }

        }
    }, 50)
    return id_read_sp
}

const x = document.getElementById('x')
const y = document.getElementById('y')
const z = document.getElementById('z')
const calculate_result = document.getElementById('calculate-result')
const x_unit = document.getElementById('x-unit')
const y_unit = document.getElementById('y-unit')
const z_unit = document.getElementById('z-unit')
const calculate_result_unit = document.getElementById('calculate-result-unit')
const calculate_select = document.getElementById('calculate-select')

const calculate_result_title = document.getElementById('calculate-result-title')
calculate_select.addEventListener('click', async () => {
    if (calculate_select.value == "two-point-length"){
        calculate_result_title.textContent = "长度："
        calculate_result.textContent = 0.0
        calculate_result_unit.textContent = "mm"
    }
    if (calculate_select.value == "three-point-circle-area"){
        calculate_result_title.textContent = "面积："
        calculate_result.textContent = 0.0
        calculate_result_unit.textContent = "mm^2"
    }
    if (calculate_select.value == "three-point-cube-volume"){
        calculate_result_title.textContent = "体积："
        calculate_result.textContent = 0.0
        calculate_result_unit.textContent = "mm^3"
    }
})
async function update_xyz(data) {
    console.log(data.current_position)
    x.textContent = data.current_position.x
    y.textContent = data.current_position.y
    z.textContent = data.current_position.z
    x_unit.textContent = "mm"
    if (x.textContent > 10) {
        x.textContent = x.textContent / 10
        x_unit.textContent = "dm"
        if (x.textContent > 10) {
            x.textContent = x.textContent / 10
            x_unit.textContent = "m"
        }
    }
    y_unit.textContent = "mm"
    if (y.textContent > 10) {
        y.textContent = y.textContent / 10
        y_unit.textContent = "dm"
        if (y.textContent > 10) {
            y.textContent = y.textContent / 10
            y_unit.textContent = "m"
        }
    }
    z_unit.textContent = "mm"
    if (z.textContent > 10) {
        z.textContent = z.textContent / 10
        z_unit.textContent = "dm"
        if (z.textContent > 10) {
            z.textContent = z.textContent / 10
            z_unit.textContent = "m"
        }
    }

    const length = read.length
    if (calculate_select.value == "two-point-length" && length >= 2) {
        const len = await calculateDistance(read[length - 2], read[length - 1])
        window.electronAPI.main("length", len)
    }
    if (calculate_select.value == "three-point-circle-area" && length >= 3){
        const {r, _} = await calculateCircleArea(read[length - 3], read[length - 2], read[length - 1])
        window.electronAPI.main("area", r)
    }
    if (calculate_select.value == "three-point-cube-volume" && length >= 4){
        const {len, width, height, _} = await calculateBoxVolume(read[length - 4], read[length - 3], read[length - 2], read[length - 1])
        window.electronAPI.main("volume", {len, width, height})
        console.log(len, width, height)
    }

    return
}

async function calculateDistance(p1, p2) {
    const dx = p2.x - p1.x;
    const dy = p2.y - p1.y;
    const dz = p2.z - p1.z;

    const result = Math.sqrt(dx * dx + dy * dy + dz * dz)
    calculate_result_unit.textContent = "mm"
    calculate_result.textContent = result
    if (calculate_result.textContent > 10) {
        calculate_result.textContent = calculate_result.textContent / 10
        calculate_result_unit.textContent = "dm"
        if (calculate_result.textContent > 10) {
            calculate_result.textContent = calculate_result.textContent / 10
            calculate_result_unit.textContent = "m"
        }
    }
    const p_element = document.createElement('p')
    p_element.textContent = "两点长度：" + calculate_result.textContent + calculate_result_unit.textContent
    view_side_data.appendChild(p_element)

    return result
}

function calculateCircleArea(p1, p2, p3) {
    // 定义向量
    const v1 = { x: p2.x - p1.x, y: p2.y - p1.y, z: p2.z - p1.z };
    const v2 = { x: p3.x - p1.x, y: p3.y - p1.y, z: p3.z - p1.z };

    // 计算法向量（向量叉积）
    const n = {
        x: v1.y * v2.z - v1.z * v2.y,
        y: v1.z * v2.x - v1.x * v2.z,
        z: v1.x * v2.y - v1.y * v2.x
    };

    // 计算向量的模
    const norm = Math.sqrt(n.x * n.x + n.y * n.y + n.z * n.z);

    // 计算圆心
    const d = 2 * (v1.x * v2.y - v1.y * v2.x);
    const h = (v1.x * (v1.x * v2.z - v2.x * v1.z) + v1.y * (v1.y * v2.z - v2.y * v1.z)) / d;
    const k = (v2.x * (v1.x * v2.z - v2.x * v1.z) + v2.y * (v1.y * v2.z - v2.y * v1.z)) / d;
    const l = (v1.x * v2.y - v1.y * v2.x) / norm;

    // 计算半径
    const r = Math.sqrt((p1.x - h) * (p1.x - h) + (p1.y - k) * (p1.y - k) + (p1.z - l) * (p1.z - l));

    // 计算圆的面积
    const area = Math.PI * r * r;
    calculate_result_unit.textContent = "mm^2"
    calculate_result.textContent = area
    if (calculate_result.textContent > 100) {
        calculate_result.textContent = calculate_result.textContent / 100
        calculate_result_unit.textContent = "dm^2"
        if (calculate_result.textContent > 100) {
            calculate_result.textContent = calculate_result.textContent / 100
            calculate_result_unit.textContent = "m^2"
        }
    }
    const p_element = document.createElement('p')
    p_element.textContent = "圆面积：" + calculate_result.textContent + calculate_result_unit.textContent
    view_side_data.appendChild(p_element)

    return {r, area}
}

async function calculateBoxVolume(p1, p2, p3, p4) {
    // 计算三条边的长度
    const len = await calculateDistance(p1, p2);
    const width = await calculateDistance(p1, p3);
    const height = await calculateDistance(p1, p4);

    // 计算体积
    const volume = len * width * height;

    calculate_result.textContent = volume
    calculate_result_unit.textContent = "mm^3"
    if (calculate_result.textContent > 1000) {
        calculate_result.textContent = calculate_result.textContent / 1000
        calculate_result_unit.textContent = "dm^3"
        if (calculate_result.textContent > 1000) {
            calculate_result.textContent = calculate_result.textContent / 1000
            calculate_result_unit.textContent = "m^3"
        }
    }
    const p_element = document.createElement('p')
    p_element.textContent = "方形体积：" + calculate_result.textContent + calculate_result_unit.textContent
    view_side_data.appendChild(p_element)

    return {len, width, height, volume}
}